package com.aspire.moss.portal.view;

import java.util.List;
import java.util.Observable;
import java.util.Observer;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewGroup.OnHierarchyChangeListener;
import android.view.animation.AnimationUtils;
import android.widget.Scroller;

public class Workspace extends ViewGroup implements DragScroller , OnHierarchyChangeListener , ViewController {

	private static final String TAG = "Workspace";
	
	int screen ; // 屏幕数
	
	int mCurrentScreen ;// 当前屏幕
	
	public static boolean isDynamic ;
	
	/**
	 * 当在屏幕上移动的速度大于多少时 翻页
	 */
	final int SNAP_VELOCITY = 400; 
	
	Context mContext;
	
	Scroller mScroller;
	
	DragController dragController;
	
	WorkspaceListener workspaceListener;
	
	WorkspaceAdapter workspaceAdapter;
	
	WorkspaceAdapterObserver  adapterObserver;
	
	int mWidth ;
	int mTouthX;
	int downX = 0;
	
	
	public Workspace(Context context, AttributeSet attrs){
		this(context, attrs, 0);
	}
	
	public Workspace(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		mContext = context;
		mScroller = new Scroller(mContext, AnimationUtils.loadInterpolator(mContext, android.R.anim.anticipate_overshoot_interpolator));
		this.setOnHierarchyChangeListener(this);
		adapterObserver = new WorkspaceAdapterObserver();
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		screen = getChildCount();
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int widthMode = MeasureSpec.getMode(widthMeasureSpec);
		if(widthMode != MeasureSpec.EXACTLY){
			throw new IllegalStateException("Workspace can only be used in EXACTLY mode.");
		}
		
		mWidth = MeasureSpec.getSize(widthMeasureSpec);
		for (int i = 0; i < getChildCount(); i++) {
            getChildAt(i).measure(widthMeasureSpec, heightMeasureSpec);
        }
		int heightMeasure  = MeasureSpec.makeMeasureSpec(mWidth, MeasureSpec.EXACTLY);
		setMeasuredDimension(widthMeasureSpec, heightMeasure);
	}
	
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int left = 0;
		View child = null;
		for(int i = 0 ; i < getChildCount(); i ++){
			child = getChildAt(i);
			child.layout(left, 0 , left + child.getMeasuredWidth(), child.getMeasuredHeight());
			left += mWidth;
		}
	}

	
	@Override
	public void computeScroll() {
		super.computeScroll();
		if(mScroller.computeScrollOffset()){
			scrollTo(mScroller.getCurrX(), 0);
			invalidate();
		}
	}
	
	@Override
	public void scrollTo(int x, int y) {
		mTouthX = x;
		super.scrollTo(x, y);
	}
	
	@Override
	public void scrollBy(int x) {
		scrollBy(x , 0);
		postInvalidate();
	}
	
	@Override
	public void scrollBy(int x, int y) {
		super.scrollBy(x, y);
		mTouthX = getScrollX();
	}
	
	@Override
	public void scrollLeft() {
		Log.d(TAG, "scrollLeft");
		int target = 0;
		if(mCurrentScreen < screen - 1){
			target = mCurrentScreen;
			target+=1;
		}else{
			target = mCurrentScreen;
		}
		scrollScreen(target);
	}

	@Override
	public void scrollRight() {
		Log.d(TAG, "scrollRight");
		int target = 0;
		if(mCurrentScreen != 0){
			target = mCurrentScreen - 1;
		}
		scrollScreen(target);
	}
	
	/**
	 * 动画移动屏幕
	 * @param screent
	 */
	private void scrollScreen(int screen){
		Log.d(TAG, "scrollScreen = " + screen + "mCurrentScreen = "+ mCurrentScreen);
		final int target = (screen * mWidth);
		mScroller.startScroll(mTouthX , 0,(target - mTouthX) , 0 , 500);
		postInvalidate();
		if(mCurrentScreen != screen){
			mCurrentScreen = screen;
			if(null != workspaceListener){
				workspaceListener.onSelectScreenChange(mCurrentScreen);
				}
		}
	}

	/**
	 * 添加celllayout
	 */
	private void addCellLayout(){
		for(int i = 0 ; i < workspaceAdapter.getCount() ; i ++){
			View view = workspaceAdapter.getGroupView(Workspace.this, i);
			if(null != view && view instanceof CellLayout){
				view.setId(i);
				addCelllayoutChild((CellLayout) view, i);
				addView(view, i);
			}else{
				Log.e(TAG, "add child view type is not Celllayou");
			}
		}
	}
	
	/**
	 * 添加celllayout子控件
	 * @param cellLayout
	 */
	private void addCelllayoutChild(CellLayout cellLayout , int group){
		List<AppInfo> apps = workspaceAdapter.getApps().get(group);
		View child = null;
		if(null == apps) return ;
		for(int i = 0 ; i < apps.size() ;i ++){
			child = workspaceAdapter.getChildView(cellLayout , group , i);
			cellLayout.addView(child);
		}
	}
	
	public int getScreen() {
		return screen;
	}

	public void setScreen(int screen) {
		this.screen = screen;
	}
	
	public void resetScreen(){
		scrollScreen(mCurrentScreen);
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		Log.d(TAG, "onTouchEvent");
		return null != dragController ? dragController.onWorspaceTouchEvent(event , this) : true;
	}
	
	@Override
	public boolean onInterceptTouchEvent(MotionEvent event) {
		int e = event.getAction();
		
		Log.d(TAG, "onInterceptTouchEvent e = " + e);
		switch (e) {
		case MotionEvent.ACTION_DOWN:
			downX = (int) event.getX();
			onTouchEvent(event);
			return false;
		case MotionEvent.ACTION_MOVE:
			return true;
		case MotionEvent.ACTION_UP:
			onTouchEvent(event);
			return false;
		}
	 	return super.onInterceptTouchEvent(event);
	}
	
	public boolean needMove(MotionEvent event){
		int x = (int) event.getX();
		int e = event.getAction();
		int mo = ViewConfiguration.getTouchSlop();
		switch (e) {
		case MotionEvent.ACTION_MOVE:
			if(Math.abs(downX - x) >= mo) return true;
			break;

		default:
			break;
		}
		return false;
	}
	
	public void setDragController(DragController dragController) {
		this.dragController = dragController;
	}
	
	public int getmWidth() {
		return mWidth;
	}

	public WorkspaceListener getWorkspaceListener() {
		return workspaceListener;
	}

	public void setWorkspaceListener(WorkspaceListener workspaceListener) {
		this.workspaceListener = workspaceListener;
	}

	@Override
	public void onChildViewAdded(View parent, View child) {
		Log.d(TAG, "onChildViewAdded workspaceListener=" + workspaceListener);
		if(null != workspaceListener){
			workspaceListener.onScreenCountChange(getChildCount());
		}
	}

	@Override
	public void onChildViewRemoved(View parent, View child) {
		Log.d(TAG, "onChildViewRemoved workspaceListener=" + workspaceListener);
		if(null != workspaceListener){
			workspaceListener.onScreenCountChange(getChildCount());
		}
	}

	public int getmCurrentScreen() {
		return mCurrentScreen;
	}

	public WorkspaceAdapter getWorkspaceAdapter() {
		return workspaceAdapter;
	}

	public void setWorkspaceAdapter(WorkspaceAdapter workspaceAdapter) {
		this.workspaceAdapter = workspaceAdapter;
		if(null != workspaceAdapter) workspaceAdapter.addObserver(adapterObserver);
	}
	

	public interface OnTouthEvent {

		public boolean onWorspaceTouchEvent(MotionEvent event,
				Workspace workspace);

	}
	
	/**
	 * 当工作空间的信息发生改变化时
	 * @author Administrator
	 *
	 */
	public interface WorkspaceListener{
		/**
		 * 当选中的屏幕发生变化时
		 * @param mCurrentScreen
		 */
		void  onSelectScreenChange(int mCurrentScreen);
		/**
		 * 当屏幕数发生变化时
		 * @param count
		 */
		void onScreenCountChange(int count);
	}
	
	/**
	 * 用于监听数据适配器的变化
	 * @author Administrator
	 *
	 */
	class WorkspaceAdapterObserver implements Observer{

		@Override
		public void update(Observable observable, Object data) {
			/**
			 * 当数据适配器发生变化时,重新把界面刷新
			 */
			if(observable instanceof WorkspaceAdapter && null != observable){
				removeAllViews();
				addCellLayout();
			}
		}
		
	}

	@Override
	public void addAppView(AppInfo appInfo) {
//		if()
		
	}

	@Override
	public void addCelllayoutView() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void removeAppView(AppInfo appInfo) {
		// TODO Auto-generated method stub
		
	}
}
